/*
 * Copyright (c) 2006-2025, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-09-30     Guotong first version
 */

#include "drv_uart2.h"
#include <rtdbg.h>

#define DBG_TAG "drv.uart2"
#ifdef DRV_DEBUG
#define DBG_LVL DBG_LOG
#else
#define DBG_LVL DBG_INFO
#endif

/* 串口2句柄 */
static UART_HandleTypeDef huart2;

/* 接收数据回调函数指针 */
static void (*uart2_rx_callback)(uint8_t) = RT_NULL;

/**
 * @brief  串口2 GPIO配置函数
 * @param  无
 * @retval 无
 */
static void uart2_gpio_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    
    /* 使能USART2时钟 */
    __HAL_RCC_USART2_CLK_ENABLE();
    
    /* 使能GPIO时钟 */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    
    /* 配置USART2 TX引脚 (PA2) */
    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    /* 配置USART2 RX引脚 (PA3) */
    GPIO_InitStruct.Pin = GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

/**
 * @brief  串口2中断处理函数
 * @param  无
 * @retval 无
 */
void USART2_IRQHandler(void)
{
    uint8_t rx_data;
    
    /* 检查接收中断标志位 */
    if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE) != RESET)
    {
        /* 读取接收到的数据 */
        rx_data = (uint8_t)(huart2.Instance->DR & 0x00FF);
        
        /* 如果设置了回调函数，则调用回调函数处理数据 */
        if (uart2_rx_callback != RT_NULL)
        {
            uart2_rx_callback(rx_data);
        }
        
        /* 清除接收中断标志位 */
        __HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_RXNE);
    }
    
    /* 处理其他可能的错误标志 */
    if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_ORE) != RESET)
    {
        __HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_ORE);
        rx_data = (uint8_t)(huart2.Instance->DR & 0x00FF);
    }
    
    /* 重新使能接收中断，确保持续响应 */
    __HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);
}

/**
 * @brief  初始化串口2
 * @param  无
 * @retval RT_EOK - 初始化成功，其他值 - 初始化失败
 */
int uart2_init(void)
{
    /* 初始化GPIO */
    uart2_gpio_init();
    
    /* 配置USART2参数 */
    huart2.Instance = USART2;
    huart2.Init.BaudRate = 115200;
    huart2.Init.WordLength = UART_WORDLENGTH_8B;
    huart2.Init.StopBits = UART_STOPBITS_1;
    huart2.Init.Parity = UART_PARITY_NONE;
    huart2.Init.Mode = UART_MODE_TX_RX;
    huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart2.Init.OverSampling = UART_OVERSAMPLING_16;
    
    /* 使用HAL库初始化UART */
    if (HAL_UART_Init(&huart2) != HAL_OK)
    {
        LOG_E("UART2 initialization failed");
        return -RT_ERROR;
    }
    
    /* 配置接收中断 */
    __HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);
    
    /* 使能USART2接收中断 */
    HAL_NVIC_SetPriority(USART2_IRQn, 3, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);
    
    LOG_D("UART2 initialized: 115200, 8N1");
    return RT_EOK;
}

/**
 * @brief  通过串口2发送数据
 * @param  data - 要发送的数据缓冲区
 * @param  len - 要发送的数据长度
 * @retval 实际发送的数据长度
 */
int uart2_send(const uint8_t *data, int len)
{
    if (data == RT_NULL || len <= 0)
    {
        return 0;
    }
    
    /* 使用HAL库发送数据 */
    if (HAL_UART_Transmit(&huart2, (uint8_t *)data, len, 1000) != HAL_OK)
    {
        LOG_E("UART2 transmit failed");
        return 0;
    }
    
    return len;
}

/**
 * @brief  设置串口2接收数据的回调函数
 * @param  cb - 回调函数指针
 * @retval 无
 */
void uart2_set_rx_callback(void (*cb)(uint8_t))
{
    uart2_rx_callback = cb;
}

/* 导出到自动初始化 */
INIT_DEVICE_EXPORT(uart2_init);
